﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Web;

namespace Library.Handlers
{
    public class ImageLogoHttpHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            AddLogoToImage(context);
        }

        public bool IsReusable
        {
            get { return false; }
        }

        private void AddLogoToImage(HttpContext context)
        {
            // Eger istenilen fotograf dosyasi bulunmuyorsa,
            // islemi bitir ve 404 hatasi gonder.
            if (!System.IO.File.Exists(context.Request.PhysicalPath))
            {
                context.Response.StatusCode = 404;
                context.Response.Status = "404 Not Found";
                return;
            }

            // Istenilen fotografi Image objesi olarak ac.
            Image image = Image.FromFile(context.Request.PhysicalPath);
            // Logoyu Image objesi olarak ac.
            Image logo = Image.FromFile(context.Server.MapPath("/Upload/Logo.png"));
            // Uzerinde bircok cizim islemini yapabilecegimiz
            // Graphics objesini null olarak olustur.
            Graphics graphic;

            // QueryString kullanilarak gonderilen "width" parametresi
            // olup olmadigina bakalim ve bu degeri "int" degere
            // donusturmeye calisalim. Eger basaramazsak, width degiskenine
            // istenilen fotografin orjinal Width degerini atayalim.
            int width = 0;
            int height;
            string widthString = context.Request.QueryString["width"];
            if (!string.IsNullOrEmpty(widthString))
            {
                if (!int.TryParse(widthString, out width))
                {
                    width = image.Width;
                }
            }

            // QueryString kullanilarak gonderilen "width" parametresi
            // sifir/negatif veya bos bir deger olabilir. Bu durumda orjinal
            // fotografin genisligini kullanmaliyiz.
            if (width <= 0)
            {
                width = image.Width;
            }

            // Eger istenilen genislik ile resmin genisligi ayni degilse
            // yuksekligi de ayni oranda kucultmemiz/buyutmemiz gerekmektedir.
            // Bu sefeple yeni yuksekligi hesaplayacagiz ve "height" degiskeninde
            // saklayacagiz.
            if (width != image.Width)
            {
                height = (int)Math.Floor(image.Height * (new decimal(width) / image.Width));
            }
            else // Buyutme/kucultme yapilmayacaksa, yukseklik orjinal fotograf ile aynidir.
            {
                height = image.Height;
            }

            // Yeni fotografimizi tutacagimiz Bitmap objemizi yeni boyutlariyla olusturalim.
            Bitmap newImage = new Bitmap(width, height, image.PixelFormat);
            // "graphic" degiskeninde tutacagimiz Graphics objemizi yeni ve bos "Bitmap" ile olusturalim.
            graphic = Graphics.FromImage(newImage);
            // Orjinal fotografimizi yeni boyutu ile resme cizelim.
            graphic.DrawImage(image, 0, 0, width, height);

            // Fotografin kalitesini ayarlayalim.
            graphic.SmoothingMode = SmoothingMode.HighQuality;
            graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;

            // Eger istenilen fotograf boyutu 150 pixel'den buyukse,
            // logoyu fotografa ekleyelim.
            if (width > logo.Width)
            {
                // Logonun fotograf uzerinde koyulacagi pozisyonu
                // Point objesi olarak tanimla.
                Point logoLocation = new Point();
                logoLocation.X = 0;
                logoLocation.Y = newImage.Height - logo.Height - 10;

                // Logoyu fotografin uzerine ciz.
                graphic.DrawImage(logo, logoLocation);
            }

            // Istemciye gonderilecek olan icerigi temizle ve
            // icerik tipinin "image/jpg" olacagini belirt
            context.Response.Clear();
            context.Response.ContentType = "image/jpg";

            // Image objesini Response objesinin "OutputStream" ozelligine yaz.
            newImage.Save(context.Response.OutputStream, ImageFormat.Jpeg);

            // Objeleri dispose et.
            graphic.Dispose();
            newImage.Dispose();
            image.Dispose();
            logo.Dispose();
        }
    }
}